﻿//
// Copyright (c) 2010
// by Chris Paterra
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated 
// documentation files (the "Software"), to deal in the Software without restriction, including without limitation 
// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and 
// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all copies or substantial portions 
// of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED 
// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF 
// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
// DEALINGS IN THE SOFTWARE.
//

using System.Collections.Specialized;
using System.ComponentModel;
using System.Linq;
using System.Web;
using System.Web.UI;
using System;
using DotNetNuke.ContentLibrary.Components.Controllers;

namespace DotNetNuke.ContentLibrary.Components.WebControls 
{

	/// <summary>
	/// A button that consists of an image and text for end users to add/remove a favorite content item.
	/// </summary>
	[DefaultProperty("ButtonCssClass"), Themeable(false)]
	[ToolboxData("<{0}:FavoriteButton runat=server> </{0}:FavoriteButton>")]
	public class FavoriteButton : ControlBase, IPostBackEventHandler, IPostBackDataHandler
	{

		#region Private Members

		private string _buttonCssClass = "CommandButton";
		private string _addImagePath = "~/images/add.gif";
		private string _removeImagePath = "~/images/delete.gif";

		/// <summary>
		/// Determines if the button is in 'add favorite' mode or remove favorite mode.
		/// </summary>
		private bool IsAddMode {
			get {
				var isEditMode = false;
				if (ViewState["IsAddMode"] != null) {
					isEditMode = Convert.ToBoolean(ViewState["IsAddMode"]);
				}
				return isEditMode;
			}
			set { ViewState["IsAddMode"] = value; }
		}

		#endregion

		#region Public Properties

		/// <summary>
		/// This is the image displayed next to the "Add Favorite" button. 
		/// </summary>
		[Bindable(true), Browsable(true), DefaultValue("~/images/add.gif"), Category("Appearance"), 
		Description("This is the image displayed next to the 'Add Favorite' link button."), Localizable(false)]
		public string AddImagePath {
			get { return _addImagePath; }
			set { _addImagePath = value; }
		}

		/// <summary>
		/// This Css class is applied to the "Add Favorite"/"Remove Favorite" link button. 
		/// </summary>
		[Bindable(true), Browsable(true), DefaultValue("CommandButton"), Category("Appearance"), 
		Description("This Css class is applied to the 'Add Favorite/Remove Favorite' link button."), Localizable(false)]
		public string ButtonCssClass {
			get { return _buttonCssClass; }
			set { _buttonCssClass = value; }
		}

		/// <summary>
		/// The title of the link in the favorites list. This can be up to 255 characters.
		/// </summary>
		/// <example>The forum module passes in the Thread Subject here.</example>
		/// <remarks>Required</remarks>
		[Browsable(false)]
		public string ContentTitle { get; set; }

		/// <summary>
		/// This is the image displayed next to the "Remove Favorite" button. 
		/// </summary>
		[Bindable(true), Browsable(true), DefaultValue("~/images/delete.gif"), Category("Appearance"), 
		Description("This is the image displayed next to the 'Remove Favorite' link button."), Localizable(false)]
		public string RemoveImagePath {
			get { return _removeImagePath; }
			set { _removeImagePath = value; }
		}

		[Bindable(true), Browsable(true), DefaultValue(false), Category("Appearance"), 
		Description("This is the image displayed next to the 'Remove Favorite' link button."), Localizable(true)]
		public bool ShowButtonText { get; set; }

        //hold
        public bool ShowButtonImage { get; set; }

		#endregion

		#region Private Methods

		/// <summary>
		/// Builds the button (image and text).
		/// </summary>
		/// <param name="writer"></param>
		private void RenderButton(HtmlTextWriter writer) {
			writer.AddAttribute(HtmlTextWriterAttribute.Class, ButtonCssClass);
			var buttonText = Services.Localization.Localization.GetString(IsAddMode ? "AddFavorite.Text" : "RemoveFavorite.Text", SharedResourceFile);
			writer.AddAttribute(HtmlTextWriterAttribute.Title, buttonText);
			writer.AddAttribute(HtmlTextWriterAttribute.Href, Page.ClientScript.GetPostBackClientHyperlink(this, buttonText));
			writer.RenderBeginTag(HtmlTextWriterTag.A);
			var imageUrl = IsAddMode ? AddImagePath : RemoveImagePath;
			writer.AddAttribute(HtmlTextWriterAttribute.Src, ResolveUrl(imageUrl));
			writer.RenderBeginTag(HtmlTextWriterTag.Img);
			writer.RenderEndTag();
			if (ShowButtonText)
			{
				writer.Write(buttonText);
			}	
			writer.RenderEndTag();
		}
	
		/// <summary>
		/// Here is where we determine if the button is in add/remove mode (based on if user has this content item as a favorite)
		/// </summary>
		private void DetermineButtonMode()
		{
			var cntController = new ContentLibraryController();
		    var colUserFavorites = cntController.GetUserFavorites(CurrentUserID, PortalID);
            var colUserCiFavorite = (from t in colUserFavorites where t.ContentItemID == CurrentContentItemID select t);

            var userVoteCount = colUserCiFavorite.Count();
            IsAddMode = userVoteCount <= 0;
		}

		/// <summary>
		/// Adds/Removes the current content item as a favorite. 
		/// </summary>
		private void UpdateUserFavorite() {
			var cntController = new ContentLibraryController();

			cntController.UpdateUserFavorite(ContentTitle, CurrentContentItemID, CurrentUserID, DateTime.Now);
		}

		#endregion

		#region Event Handlers

		/// <summary>
		/// This renders the user interface of this control.
		/// </summary>
		/// <param name="writer"></param>
		/// <remarks>This is used because the button is a single element and this is better for performance (vs. Render).</remarks>
		protected override void RenderContents(HtmlTextWriter writer) 
		{
			if (CurrentContentItemID < 1) return;
			if (!HttpContext.Current.Request.IsAuthenticated) return;
			DetermineButtonMode();
			RenderButton(writer);
			// consider adding an optional message here
		}

		#endregion

		#region IPostBackDataHandler Implementation

		/// <summary>
		/// 
		/// </summary>
		/// <param name="postDataKey"></param>
		/// <param name="postCollection"></param>
		/// <returns></returns>
		public bool LoadPostData(string postDataKey, NameValueCollection postCollection) {
			return true;
		}

		/// <summary>
		/// 
		/// </summary>
		public void RaisePostDataChangedEvent() {
		}

		#endregion

		#region IPostBackEventHandler Implementation

		/// <summary>
		/// Post back event that sets the button mode and then updates the data store.
		/// </summary>
		/// <param name="eventArgument"></param>
		public void RaisePostBackEvent(string eventArgument)
		{
			switch (eventArgument) {
				case "Add":
					IsAddMode = false;
					break;
				default:
					IsAddMode = true;
					break;
			}

			UpdateUserFavorite();
		}

		#endregion

	}
}